# -*- coding: utf-8 -*-

import wave
from pylab import *
import Image

def frames2signal(frames, sampwidth):
    """
    Составляет сигнал из строки фрэймов, которую вернул Wave_read.readframes()
    """
    
    for i in xrange(0, len(frames), sampwidth):
        # Составляем целое число из фреймов. Некрасиво, зато быстро.
        mostSignificant = i + sampwidth - 1
        res = ord(frames[mostSignificant])
        for j in xrange(mostSignificant - 1, i - 1, -1):
            res <<= 8
            res |= ord(frames[j]);
        # res --- это и есть значение сигнала
        yield res

def signal2frames(sig, sampwidth):
    mask = 0x000000ff
    for num in sig:
        tmp = int(round(num))
        for i in xrange(sampwidth):
            yield chr(tmp & mask)
            tmp >>= 8

def fig2data ( fig ):
    """
    @brief Convert a Matplotlib figure to a 4D numpy array with RGBA channels and return it
    @param fig a matplotlib figure
    @return a numpy 3D array of RGBA values
    """
    # draw the renderer
    fig.canvas.draw ( )
 
    # Get the RGBA buffer from the figure
    w,h = fig.canvas.get_width_height()
    buf = np.fromstring ( fig.canvas.tostring_argb(), dtype=np.uint8 )
    buf.shape = ( w, h,4 )
 
    # canvas.tostring_argb give pixmap in ARGB mode. Roll the ALPHA channel to have it in RGBA mode
    buf = np.roll ( buf, 3, axis = 2 )
    return buf

def fig2img ( fig ):
    """
    @brief Convert a Matplotlib figure to a PIL Image in RGBA format and return it
    @param fig a matplotlib figure
    @return a Python Imaging Library ( PIL ) image
    """
    # put the figure pixmap into a numpy array
    buf = fig2data ( fig )
    w, h, d = buf.shape
    return Image.fromstring( "RGBA", ( w ,h ), buf.tostring( ) )

w = wave.open('samples/sample1.wav')
nchannels = w.getnchannels()
framerate = w.getframerate()
sampwidth = w.getsampwidth()
sig = array(list(frames2signal(w.readframes(1 << 32), sampwidth)))
w.close()
sig /= 1 << 24

w = wave.open('samples/sample1o.wav', 'w')
sampwidth = 1
w.setnchannels(nchannels)
w.setframerate(framerate)
w.setsampwidth(sampwidth)
frames = ''.join(signal2frames(sig, sampwidth))
fig = figure(figsize = (16, 10))
plot = fig.add_subplot(111)
plot.plot(array(list(frames2signal(frames, sampwidth))))
im = fig2img(fig)
im.show()
w.writeframes(frames)
w.close()
